package com.ecar.api.rest.pay;

import com.ecar.api.rest.AbstractResource;
//import com.ecar.api.service.NotifyService;
//import com.ecar.api.service.PassengerService;
//import com.ecar.api.service.StationTerminalService;
//import com.ecar.api.service.UserService;
//import com.ecar.api.service.booking.AgencyService;
//import com.ecar.api.service.booking.BookingService;
//import com.ecar.api.service.booking.QrRecordService;
//import com.ecar.api.support.store.ConfigStore;
//import com.ecar.api.support.store.Configs;
import com.ecar.api.support.util.PasswordUtil;
import com.ecar.api.support.util.Props;
import com.ecar.api.support.util.Redis;
import com.ecar.api.support.util.UserUtil;
import com.ecar.api.support.util.WXLoginUtil;
import com.ecar.api.support.util.WXValidator;
import com.ecar.api.support.util.WechatXMLParser;
import com.ecar.cache.BeanSerializer;
import com.ecar.common.dto.DataBean;
import com.ecar.common.exception.MyException;
import com.ecar.common.util.HttpClientUtil;
import com.ecar.common.util.JSONUtil;
import com.ecar.common.util.StringUtil;
import com.ecar.core.common.entity.User;
//import com.ecar.core.model.Passenger;
//import com.ecar.core.model.Privilege;
//import com.ecar.core.model.booking.StationStartTerminal;
//import com.ecar.core.model.booking.TicketAgency;
import net.sf.json.JSONObject;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.net.URLDecoder;
import java.text.MessageFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

/**
 * 微信授权回调
 * Created by 30 on 2018/1/6.
 */
@Component
@Scope("prototype")
@Path("/wx")
public class WechatRest extends AbstractResource {

	private WXLoginUtil wxLoginUtil = WXLoginUtil.getInstance();

	@Context
	HttpServletRequest request;

	@Context
	HttpServletResponse response;

	@Context
	UriInfo uriInfo;

	/**
	 * Wap端微信授权入口
	 * @return
	 */
	@GET
	@Path("/auth")
	public Response auth() {
		String state = request.getParameter("state");//重定向后会带上state参数，开发者可以填写a-zA-Z0-9的参数值，最多128字节，该值会被微信原样返回，我们可以将其进行比对，防止别人的攻击。
//		String ecarTok = request.getParameter("ecarTok");
		if (StringUtil.isEmpty(state) || state.equalsIgnoreCase("undefined")) state = "0";
		URI uri;
//		if (StringUtil.isNotEmpty(ecarTok)) {
//			uri = wxLoginUtil.getWxAuthRedirectURI(state, "?ecarTok=" + ecarTok);
//		} else {
			uri = wxLoginUtil.getWxAuthRedirectURI(state);
//		}
		if (uri == null) return Response.status(404).build();

		return Response.temporaryRedirect(uri).build();//Jersey下的Response可以实现类似servlet的跳转
	}


	/**
	 * 微信授权登录回调地址
	 * @return
	 */
	@GET
	@Path("/h5")
	public Response redirectH5() {
		String code = request.getParameter("code");//code（授权码）怎么可以直接获取？
		String state = request.getParameter("state");//传的userId值？？
//		String key = request.getParameter("key");//key和agency是代售的，具体要结合前端看下
		String ecarTok = request.getParameter("ecarTok");//回调时可将我们业务需要参数加在url后面
		if (StringUtil.isEmpty(code)) return Response.status(400).build();

		String phone = null;
		String accessToken = null;
		String refreshToken = null;
//		int userId = Integer.parseInt(state);
		String openid = null;
		URI uri=null;
		JSONObject token = wxLoginUtil.getAccessToken(code);
		if (token.containsKey("access_token")) {
			String access_token = token.getString("access_token");
			openid = token.getString("openid");
			JSONObject userinfo = wxLoginUtil.getUserInfo(access_token, openid);
			if (userinfo.containsKey("nickname")) {
				User user;
//				if (userId > 0) {        // 待支付用户绑定openid
//					try {
//						user = wxBindOpenid(userinfo, openid, userId,ecarTok);
//					} catch (MyException e) {
//						String thePhone = e.getMessage();
//						thePhone = thePhone.substring(thePhone.length() - 3);
//						String msg = "您的微信号已绑定尾数为" + thePhone + "的手机，请使用该手机号或微信授权登录";
//						URI uri = wxLoginUtil.getWapMessageUri(msg);
//						return Response.seeOther(uri).build();
//					}
//				} else {    //微信授权登录
					user = wxAuthLogin(openid, userinfo);
					int userId;
					if (user != null) 
						userId = user.getId();
//				}

				phone = user != null ? user.getPhone() : null;
				if (StringUtil.isNotEmpty(phone)) {
					String password = PasswordUtil.desdecode(user.getPassword());
					JSONObject userToken = wxLoginUtil.getWapUserToken(phone, password);
					if (userToken != null && userToken.containsKey("access_token")) {
						accessToken = userToken.getString("access_token");
						refreshToken = userToken.getString("refresh_token");
					}
				}
			}
			
//			if (StringUtil.isNotEmpty(key)) {        // 扫码快速下单流程
//				if (StringUtil.isNotEmpty(accessToken)) {
//					//==============================================跳转到我们的h5下单页面=================================================
//					
//					uri = wxLoginUtil.getWapSubmitUri(key, userId, accessToken, refreshToken);
//				} else {
					uri = wxLoginUtil.getWapNoauthUri(openid,userinfo);
//				}
//			 else {        // 正常授权登录流程
//				uri = wxLoginUtil.getWapUri(openid, userId, accessToken, phone, refreshToken);
//			}
			
		}
		return Response.seeOther(uri).build();
	}

//	/**
//	 * 快速下单入口
//	 * @return
//	 */
//	@GET
//	@Path("/qr/entry")
//	public Response flash() {
//		try {
//			String st = request.getParameter("st");
//			String termName = request.getParameter("ed");
//			if (StringUtil.isEmpty(st) && StringUtil.isEmpty(termName))
//				throw new MyException("地址参数错误。");
//
//			termName = URLDecoder.decode(termName, "UTF-8");
//			int startId = Integer.parseInt(st);
//			StationStartTerminal runline = terminalService.getRunline(startId, termName);
//			if (runline == null) throw new MyException("无效的线路。");
//
//			URI uri;
//			String value = (String) ConfigStore.getValue(Configs.FLASH_ORDER);
//			if ("true".equalsIgnoreCase(value)) {
//				String param = bookingService.setCacheOrder(runline);
//				if (StringUtil.isEmpty(param)) throw new MyException("没有可快速下单的数据。");
//
//				uri = wxLoginUtil.getWapFlashRedirectURI(param);
//			} else {
//				uri = wxLoginUtil.getWapShiftUri(runline.getStationStart().getId(),
//												 runline.getStationTerminal().getId(),
//												 runline.getStationStart().getName(),
//												 runline.getStationStart().getCity());
//			}
//			if (uri != null) return Response.seeOther(uri).build();
//		} catch (Exception e) {
//			if (e instanceof MyException) log.info(e.getMessage());
//			else e.printStackTrace();
//		}
//		return Response.seeOther(wxLoginUtil.getWap404Uri()).build();
//	}
//
	/**
	 * 用户绑定微信openid，使用户能进行公众号支付
	 * @param userinfo
	 * @param openid
	 * @param userId
	 * @return
	 * @throws MyException
	 */
	private User wxBindOpenid(JSONObject userinfo, String openid, int userId,String ecarTok) throws MyException {
		String unionid = userinfo.containsKey("unionid") ? userinfo.getString("unionid") : null;

		String device = "wechat";
		String deviceInfo = openid + "_WAP";
		User user=UserUtil.getUser(userId, ecarTok);
//		Passenger passenger = passengerService.getById(userId);
		if (user != null) {
			User another=UserUtil.getUserByOpenId(openid);
//			Passenger another = passengerService.getByOpenId(openid);
			if (another != null) {
				if (StringUtil.isEmpty(another.getPhone())) {
					try {
						UserUtil.deleteUserByUserId(userId);
//						passengerService.deleteById(another.getId());
					} catch (Exception e) {
						e.printStackTrace();
					}
				} else {
					throw new MyException(another.getPhone());
				}
			}
			user.setUnionid(unionid);
			user.setOpenid(openid);
			if (user.getDevice() == null) {
				user.setDevice(device);
				user.setDeviceInfo(deviceInfo);
			}

//			String key = Redis.K.BK_AGENCY.to(openid);
//			String agencyCode = Redis.c.get(key);
//			if (StringUtil.isNotEmpty(agencyCode)) {
//				TicketAgency agency = agencyService.getByCode(agencyCode);
//				if (agency != null && agency.isValid()) {
//					passenger.setAgencyId(agency.getId());
//					passenger.setAgencyCode(agencyCode);
//					passenger.setAgencyName(agency.getName());
//					passenger.setAgencyTime(new Date());
//				}
//				Redis.c.del(key);
//			}
			UserUtil.updateUserByUserId(user);
//			passengerService.update(passenger);
			Redis.c.set(Redis.K.USER.to(userId).getBytes(),
						BeanSerializer.serialize(user),
						Redis.NX.getBytes(), Redis.EX.getBytes(), Redis.M15);
		}
		return user;
	}

//	/**
//	 * 获取代售点ID
//	 * @param agencyCode
//	 * @return
//	 */
//	private TicketAgency getAgency(String agencyCode) {
//		if (StringUtil.isEmpty(agencyCode)) return null;
//
//		TicketAgency agency = agencyService.getByCode(agencyCode);
//		if (agency == null || !agency.isValid()) return null;
//
//		return agency;
//	}

	/**
	 * 微信授权登录流程
	 * @param openid
	 * @param userinfo
	 * @return
	 */
	private User wxAuthLogin(String openid, JSONObject userinfo) {
		String unionid = userinfo.containsKey("unionid") ? userinfo.getString("unionid") : null;
		String device = "wechat";
		String deviceInfo = openid + "_WAP";
//		TicketAgency agency = getAgency(agencyCode);
//		Passenger passenger = passengerService.getByOpenId(openid);
		User user=UserUtil.getUserByOpenId(openid);
//		if (passenger == null) passenger = passengerService.getByUnionId(unionid);
		User newUser = null;
		if (user == null) {
			newUser=new User();
			user.setUnionid(unionid);
			user.setOpenid(openid);
			user.setDevice(device);
			user.setDeviceInfo(deviceInfo);
//			UserUtil.insertUserByOpenId(newUser);//插入用户信息
			log.debug("新用户授权流程。");
//			cacheUserInfo(openid, unionid, device, deviceInfo, userinfo);
//			return null;
		}

		if (StringUtil.isEmpty(user.getPhone())) {        // 删除未绑定手机号的历史用户
			try {
				log.info("删除已授权但未绑定手机号用户（处理历史遗留问题）: {}, {}", openid, unionid);
//				passengerService.deleteById(passenger.getId());
				UserUtil.deleteUserByUserId(user.getId());
			} catch (Exception e) { e.printStackTrace(); }
			cacheUserInfo(openid, unionid, device, deviceInfo, userinfo);
//			return null;
		}

		log.debug("已绑定用户，正常授权登录");
		if (StringUtil.isEmpty(newUser.getUnionid())) newUser.setUnionid(unionid);
		if (StringUtil.isEmpty(newUser.getOpenid())) newUser.setOpenid(openid);
//		if (agency != null) {
//			passenger.setAgencyId(agency.getId());
//			passenger.setAgencyCode(agency.getCode());
//			passenger.setAgencyName(agency.getName());
//			passenger.setAgencyTime(new Date());
//		}
		newUser.setLastLoginTime(new Date());
//		passengerService.update(passenger);
		UserUtil.updateUserByUserId(newUser);
		Redis.c.set(Redis.K.USER.to(user.getId()).getBytes(),
					BeanSerializer.serialize(user),
					Redis.NX.getBytes(), Redis.EX.getBytes(), Redis.M15);
		return newUser;
	}

	/**
	 * 微信授权用户生成乘客对象并缓存到 Redis
	 * @param openid
	 * @param uid
	 * @param userinfo
	 */
	private void cacheUserInfo(String openid, String uid, String device,
							   String deviceInfo, JSONObject userinfo) {
		String nickname = userinfo.getString("nickname");
		int gender = userinfo.getInt("sex") - 1;
		String province = userinfo.getString("province");
		String city = userinfo.getString("city");
		String country = userinfo.getString("country");
		String avatar = userinfo.getString("headimgurl");
		String address = country + " " + province + " " + city;

		String password = PasswordUtil.generate(8);
		password = PasswordUtil.desencode(password);
		 User user = new User(openid, uid, password,
											gender, address, device, deviceInfo);
//		if (agency != null) {
//			passenger.setAgencyId(agency.getId());
//			passenger.setAgencyCode(agency.getCode());
//			passenger.setAgencyName(agency.getName());
//			passenger.setAgencyTime(new Date());
//		}
		
//		Set<Privilege> privileges = new HashSet<>();
//		Privilege privilege = userService.getPrivilege(Privilege.PASSENGER);
//		if (privilege != null) privileges.add(privilege);
//		passenger.setPrivileges(privileges);
//		passenger.setLastLoginTime(new Date());
		byte[] bytes = BeanSerializer.serialize(user);
		Redis.c.setex(Redis.K.WXAUTH.to(openid).getBytes(), Redis.M15, bytes);
	}

//	/**
//	 * 微信对接验证
//	 * @return
//	 */
//	@GET
//	@Path("/push/evt")
//	public Response wechatValidation() {
//		if (WXValidator.checkSignature(request, Props.getValue("weixin.token"))) {    // 验证微信请求，成功返回echostr参数的值
//			return Response.ok(request.getParameter("echostr"), MediaType.TEXT_PLAIN).build();
//		}
//		return Response.status(200).build();
//	}
//
//	/**
//	 * 微信事件推送
//	 * @return
//	 */
//	@POST
//	@Path("/push/evt")
//	public Response wechatEvent() {
//		if (WXValidator.checkSignature(request, Props.getValue("weixin.token"))) {
//			String outStr = null;
//			try {
//				Map<String, String> params = WechatXMLParser.parseXML(request);
//				String msgType = params.get("MsgType");
//				if ("event".equals(msgType)) {
//					outStr = handleEvent(params);
//				} else {
//					outStr = HttpClientUtil.httpPostContent(Props.getValue("weixin.hanwechat"),
//															WechatXMLParser.map2XmlString(params));
//				}
//			} catch (Exception e) {
//				e.printStackTrace();
//			}
//			if (StringUtil.isNotEmpty(outStr)) {
//				log.debug("response to wx: {}", outStr);
//				return Response.ok(outStr, MediaType.TEXT_PLAIN).build();
//			}
//		}
//		return Response.status(200).build();
//	}
//
//	private String handleEvent(Map<String, String> params) throws IOException {
//		String event = params.get("Event");
//		if ("subscribe".equals(event)) {
//			log.info("subscribe: {}", params.toString());
//			// 未关注，关注时推送场景值
//			String eventKey = params.get("EventKey");
//			if (StringUtil.isNotEmpty(eventKey) && eventKey.startsWith("qrscene_")) {
//				eventKey = eventKey.substring(8);
//				if (eventKey.startsWith("QR_")) {
//					int recordId = Integer.parseInt(eventKey.substring(3));
//					return recordService.checkQrRecord(recordId, params);
//				}
//				int agencId = Integer.parseInt(eventKey);
//				return agencyService.checkAgencyRelation(agencId, params);
//			}
//
//			String openId = params.get("FromUserName");
//			String wxid = params.get("ToUserName");
//			String href = Props.getValue("weixin.wap") + Props.getValue("weixin.wap.agency");
//			String reply = Props.getValue("weixin.reply");
//			reply = MessageFormat.format(reply, href);
//
//			Map<String, String> msg = new HashMap<>();
//			msg.put("FromUserName", wxid);
//			msg.put("ToUserName", openId);
//			msg.put("MsgType", "text");
//			msg.put("CreateTime", String.format("%d", System.currentTimeMillis() / 1000));
//			msg.put("Content", reply);
//			return WechatXMLParser.map2XmlString(msg);
//		} else if ("SCAN".equals(event)) {
//			log.info("SCAN: {}", params.toString());
//			// 已关注，扫描时推送场景值
//			String eventKey = params.get("EventKey");
//			if (StringUtil.isNotEmpty(eventKey)) {
//				if (eventKey.startsWith("QR_")) {
//					int recordId = Integer.parseInt(eventKey.substring(3));
//					return recordService.checkQrRecord(recordId, params);
//				}
//				int agencId = Integer.parseInt(eventKey);
//				return agencyService.checkAgencyRelation(agencId, params);
//			}
//		}
//		return HttpClientUtil.httpPostContent(Props.getValue("weixin.hanwechat"),
//											  WechatXMLParser.map2XmlString(params));
//	}
}
